/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.devs.benchmark.topology;

import java.util.List;
import org.devs.benchmark.Util;
import org.devs.benchmark.modeling.CoupledType;
import org.devs.benchmark.modeling.ModelType;

/**
 *
 * @author Alejandro Moreno
 */
public class Mesh extends Network {

    int width;
    int height;

    public Mesh(String name, int width, int height, Class message) throws Exception {

        super(name, message);

        if (width < 1 || height < 1 ) {
            throw new Exception("Parameters are incorrect");
        }

        this.width = width;
        this.height = height;
        
    }

    

    public Mesh(String name, int width, int height, Class message, int recursion) throws Exception {

        super(name,message, recursion);

        if (width < 1 || height < 1 || recursion < 1) {
            throw new Exception("Parameters are incorrect");
        }

        this.width = width;
        this.height = height;

    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }



    public void buildModel(){
        
        super.setModel(this.createNetwork(this.name, this.width, this.height,super.message, this.recursion));
    }



    public void connectNodes(CoupledType coupled, int width) {

        if (coupled.getModels().size() > 0) {

            List<ModelType> models = coupled.getModels();


             for (int i = 0; i < 4; i++) {

                addConnectionToParent(coupled, 0, i, i);
                addConnectionFromParent(coupled, 0, i, i);

            }

            for (int i = 0; i < (models.size() - 1); i++) {

                int j = (i + 1);
                if (j % width != 0) {

                    addConnection(coupled, i, 1, j, 3);
                    addConnection(coupled, j, 3, i, 1);

                }
                int k = (i + width);
                
                if (k < models.size()) {

                    addConnection(coupled, i, 2, k, 0);
                    addConnection(coupled, k, 0, i, 2);

                }

            }

        }


    }

    public ModelType createNetwork(String name, int width, int height, Class message, int recursion) {
        return create(name, width, height, message,"", recursion);
    }

    

    public ModelType create(String name, int width, int height, Class message,String id, int recursion) {

        CoupledType coupled = null;

        if (recursion > 0) {

            coupled = new CoupledType(name + "_Coupled" + id, Util.createInports(4, message), Util.createOutports(4, message));

            ModelType mod = null;
            for (int j = 0; j < height; j++) {

                for (int i = 0; i < width; i++) {
                    mod = create(name, width, height, message,id + "_" + j + "_" + i, recursion - 1);
                    coupled.getModels().add(mod);                    
                }


            }

            connectNodes(coupled,width);

        } else {


            coupled = buildNode(name, 4, message, id);


        }

        return coupled;

    }

    }
